#include "bsp_usart6.h"

/* BSP-USART6 串口 */

/*
 * USART6_TX : PC6-AF7
 * USART6_RX : PC7-AF7
*/


/* define */

#define USART_PORT USART6

/* static var */
static USART_HandleTypeDef usart6_handle;

static void (*usart6_irq_rx_handler)(int) = NULL;



/* static func */


void USART6_IRQHandler(void)
{
    uint32_t reg_isr = USART_PORT->ISR;
    uint32_t reg_icr;
    int ch;
    static uint8_t usart6_irq_rx_cnt = 0;

    /* 接收中断 */
    if (reg_isr & USART_ISR_RXNE)
    {
        ch = (uint8_t)USART_PORT->RDR;
        usart6_irq_rx_cnt++;
        if (usart6_irq_rx_handler != NULL)
        {
            usart6_irq_rx_handler(ch);
            if (usart6_irq_rx_cnt >= 64)
            {
                usart6_irq_rx_handler(-1);
                usart6_irq_rx_cnt = 0;
            }
        }
    }

    /* 空闲中断 */
    if (reg_isr & USART_ISR_IDLE)
    {
        ch = -1;
        usart6_irq_rx_cnt = 0;
        if (usart6_irq_rx_handler != NULL)
        {
            usart6_irq_rx_handler(-1);
        }
    }

    /* 清除中断标志位 USART_ICR_TCCF  */
    reg_icr = UART_CLEAR_PEF | UART_CLEAR_FEF | UART_CLEAR_NEF | UART_CLEAR_OREF | \
                UART_CLEAR_IDLEF | UART_CLEAR_LBDF | UART_CLEAR_CTSF | \
                UART_CLEAR_CMF | UART_CLEAR_WUF | UART_CLEAR_TXFECF;
    SET_BIT(USART_PORT->ICR, reg_icr);
}


/* exprot func */


/**
 * @brief 获取USART6句柄
 * 
 * @return USART_HandleTypeDef* 
 */
USART_HandleTypeDef *bsp_usart6_get_handle(void)
{
    return &usart6_handle;
}

/**
 * @brief 设置串口6终端处理函数
 * 
 * @param func 回调函数
 */
void bsp_usart6_set_irq_rx_handler(void (*func)(int))
{
    usart6_irq_rx_handler = func;
}

/**
 * @brief 串口6发送1个字符(同步发送模式)
 * 
 * @param ch 发送字符
 * @return int 
 */
int bsp_usart6_put_char(int ch)
{
    while ((USART_PORT->ISR & USART_ISR_TC) == 0); //等待上次发送完成
    USART_PORT->TDR = (uint8_t)ch;
    return ch;
}

/**
 * @brief 串口6发送缓存
 * 
 * @param buff 缓存
 * @param size 缓存大小
 * @return int 
 */
int bsp_usart6_send_buff(uint8_t *buff, uint32_t size)
{
    int i;

    for (i = 0; i < size; i++)
    {
        while ((USART_PORT->ISR & USART_ISR_TC) == 0); //等待上次发送完成
        USART_PORT->TDR = (uint8_t)buff[i];
    }
    return size;
}


/**
 * @brief usart6串口初始化
 * 
 * @param bound 波特率
 */
void bsp_usart6_init(uint32_t bound)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_USART6_CLK_ENABLE();

    /* USART6_TX: PC6-AF7 */
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART6;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* USART6_RX: PC7-AF7 */
    GPIO_InitStruct.Pin = GPIO_PIN_7;
    GPIO_InitStruct.Alternate = GPIO_AF7_USART6;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* 串口配置: 8位, 1停止位, 无奇偶校验, 无流控 */
    HAL_USART_DeInit(&usart6_handle);

    usart6_handle.Instance = USART_PORT;
    usart6_handle.Init.BaudRate = bound;
    usart6_handle.Init.WordLength = USART_WORDLENGTH_8B;
    usart6_handle.Init.StopBits = USART_STOPBITS_1;
    usart6_handle.Init.Parity = USART_PARITY_NONE;
    usart6_handle.Init.Mode = USART_MODE_TX_RX;
    usart6_handle.Init.CLKLastBit = USART_LASTBIT_DISABLE;
    usart6_handle.Init.CLKPhase = USART_PHASE_1EDGE;
    usart6_handle.Init.CLKPolarity = USART_POLARITY_LOW;
    usart6_handle.Init.FIFOMode = USART_FIFOMODE_DISABLE;
    usart6_handle.Init.NSS = USART_NSS_HW;
    // usart6_handle.Init.Prescaler = USART_PRESCALER_DIV1;
    usart6_handle.Init.SlaveMode = USART_SLAVEMODE_DISABLE;
    usart6_handle.Init.RXFIFOThreshold = USART_RXFIFO_THRESHOLD_1_8;
    usart6_handle.Init.TXFIFOThreshold = USART_TXFIFO_THRESHOLD_1_8;
    if (HAL_USART_Init(&usart6_handle) != HAL_OK)
    {
        // Error_Handler(__FILE__, __LINE__);
    }

    /* 中断 */
    HAL_NVIC_SetPriority(USART6_IRQn, 9, 0);
    HAL_NVIC_EnableIRQ(USART6_IRQn);

    // SET_BIT(USART_PORT->ICR, USART_ICR_TCCF);  /* 清除TC发送完成标志 */
    SET_BIT(USART_PORT->RQR, USART_RQR_RXFRQ); /* 清除RXNE接收标志 */
    // USART_CR1_PEIE | USART_CR1_RXNEIE
    SET_BIT(USART_PORT->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE | USART_CR1_IDLEIE); /* 使能PE,RX接收,IDLE空闲中断 */

}






